package model

import (
	"app/common/constant"
	"app/common/funcs"
	"app/pkg/config"
	"app/pkg/db"
	"errors"
	"fmt"

	"github.com/garyburd/redigo/redis"
)

type SmsLogModel struct {
	CommonStruct
	Phone string `gorm:"column:phone" json:"phone"`
	Ip    string `gorm:"column:ip" json:"ip"`
	Code  string `gorm:"column:code" json:"code"`
	State int8   `gorm:"column:state" json:"state"`
	Err   string `gorm:"column:err" json:"err"`
	Ymd   string `gorm:"-" json:"ymd"`
}

func NewSmsLogModel() *SmsLogModel {
	return &SmsLogModel{}
}

func (m *SmsLogModel) TableName() string {
	return "sms_log"
}

func (m *SmsLogModel) NewItem(phone string, code string, state int8, errMsg string, ip string) error {
	conn, err := db.DB.MysqlDB.DefaultGormDB()
	if err != nil {
		return err
	}
	newItem := &SmsLogModel{
		Phone: phone,
		Code:  code,
		State: state,
		Err:   errMsg,
		Ip:    ip,
	}
	return conn.Model(&m).Omit("create_time", "update_time").Create(&newItem).Error
}

func (m *SmsLogModel) GetSendCount(phone, ymd string) (count int64, err error) {
	conn, err := db.DB.MysqlDB.DefaultGormDB()
	if err != nil {
		return
	}
	err = conn.Model(&m).Where("phone = ? and ymd = ?", phone, ymd).Count(&count).Error
	return
}

func (m *SmsLogModel) GetSendCountFromRedis(phone, ymd string) (count int64) {
	count, _ = redis.Int64(db.DB.RedisPool.Get().Do("GET", fmt.Sprintf("%s_%s", ymd, phone)))
	return count
}

func (m *SmsLogModel) IncreSendCountRedis(phone, ymd string) error {
	_, err := db.DB.RedisPool.Get().Do("INCR", fmt.Sprintf("%s_%s", ymd, phone))
	return err
}

func (m *SmsLogModel) UpdateExpireSendCount(phone, ymd string, ttl int64) error {
	_, err := db.DB.RedisPool.Get().Do("EXPIRE", fmt.Sprintf("%s_%s", ymd, phone), ttl)
	return err
}

func (m *SmsLogModel) VerifySmsCode(phone, code string, usedFor int) error {
	canUseSuper := config.Config.AliSMSVerify.UseSupperPhone
	//使用草鸡验证码校验
	if config.Config.AliSMSVerify.SuperCode != "" && code == config.Config.AliSMSVerify.SuperCode && funcs.Contains(phone, canUseSuper) {
		return nil
	}
	var accountKey string
	switch usedFor {
	case constant.VerificationCodeForRegister:
		accountKey = phone + "_" + constant.VerificationCodeForRegisterSuffix
	case constant.VerificationCodeForLogin:
		accountKey = phone + "_" + constant.VerificationCodeForLoginSuffix
	case constant.VerificationCodeForReset:
		accountKey = phone + "_" + constant.VerificationCodeForResetSuffix
	case constant.VerificationCodeForSwitchPhone:
		accountKey = phone + "_" + constant.VerificationCodeForSwitchPhoneSuffix
	case constant.VerificationCodeForEditPayPass:
		accountKey = phone + "_" + constant.VerificationCodeForEditPayPassSuffix
	}
	redisCode, err := db.DB.GetAccountCode(accountKey)
	if err != nil || redisCode == "" {
		return errors.New("验证码验证失败")
	}
	//比较验证码
	if redisCode != code {
		return errors.New("验证码验证失败")
	}
	//验证通过清除验证码
	db.DB.DelAccountCode(accountKey)
	return nil
}

func (m *SmsLogModel) OverviewDel(t string) {
	conn, err := db.DB.MysqlDB.DefaultGormDB()
	if err != nil {
		return
	}
	conn.Where("create_time <= ?", t).Delete(&SmsLogModel{})
}
